package com.example.demo.service.serviceImpl;

import com.example.demo.pojo.ActiveUser;
import com.example.demo.pojo.Page;
import com.example.demo.pojo.User;
import com.example.demo.repository.UserRepository;
import com.example.demo.repository.repositoryImpl.UserRepositoryImpl;
import com.example.demo.service.UserService;
import com.querydsl.core.Tuple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    private final Integer CURRENT_COUNT = 3;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserRepositoryImpl userRepositoryImpl;

    @Override
    public Page searchUsers(int currentPage, String keywords) {

        Page page = new Page();
        Integer num = userRepositoryImpl.countAll(keywords);
        int start = (currentPage - 1) * CURRENT_COUNT;
        int listNum = CURRENT_COUNT;
        List<User> userList;
        if (keywords.equals("")) {
            userList = userRepository.findByPage(start, listNum);
        } else {
            userList = userRepositoryImpl.findByPage(start, listNum, keywords);
        }
        int totalPage = (int)Math.ceil(num * 1.0 / CURRENT_COUNT);
        page.setTotalCount(num);
        page.setTotalPage(totalPage);
        page.setCurrentCount(listNum);
        page.setCurrentPage(currentPage);
        page.setListForObject(userList);
        return page;
    }

    @Override
    public boolean addUser(User user) {

        User user1 = userRepository.findUserByU_name(user.getU_name());
        if (user1 != null) {
            return false;
        }
        user.setU_createTime(new Date());
        BigDecimal asset = user.getU_asset();
        int level = calLevel(asset);
        user.setDelete(false);
        user.setU_level(level);
        User user2 = userRepository.save(user);
        if (user2 != null && user2.getU_id() != null) {
            return true;
        }
        return false;
    }

    public int calLevel(BigDecimal asset) {
        int level;
        if (asset.longValue() < 100000) {
            level = 1;
        } else if (asset.longValue() < 500000) {
            level = 2;
        } else if (asset.longValue() < 1000000) {
            level = 3;
        } else if (asset.longValue() < 3000000) {
            level = 4;
        } else {
            level = 5;
        }
        return level;
    }

    @Override
    public boolean editUser(User user) {

        User user1 = userRepository.findUserByU_id(user.getU_id());
        if (user1 == null) {
            return false;
        }
        BigDecimal asset = user.getU_asset();
        int level = calLevel(asset);
        user.setU_level(level);
        Date time = user1.getU_createTime();
        user.setU_createTime(time);
        User user2 = userRepository.save(user);
        if (user2 != null && user2.getU_id() != null) {
            return true;
        }
        return false;
    }

    @Override
    public void deleteUser(Integer id) {
        userRepository.deleteUser(id, true);
    }

    @Override
    public User findUserById(Integer id) {

        User user = userRepository.findUserByU_id(id);
        return user;
    }

    @Override
    public User findUserByName(String username) {

        User user = userRepository.findUserByU_name(username);
        return user;
    }

    @Override
    public Page findActiveUser(int currentPage) {

        Page page = new Page();
        int start = (currentPage - 1) * CURRENT_COUNT;
        int listNum = CURRENT_COUNT;
        List<Tuple> tupleList = userRepositoryImpl.findActiveUser();
        Map<Integer, ActiveUser> userMap = new HashMap<>();
        List<ActiveUser> userList = new ArrayList<>();
        for (Tuple tuple : tupleList) {
            ActiveUser au = new ActiveUser();
            au.setId(tuple.get(0, Integer.class));
            au.setUsername(tuple.get(1, String.class));
            au.setAsset(tuple.get(2, BigDecimal.class));
            au.setTransactionTime(tuple.get(3, Date.class));
            au.setAmount(tuple.get(4, BigDecimal.class));
            if (!userMap.containsKey(au.getId())) {
                userMap.put(au.getId(), au);
            } else if (userMap.get(au.getId()).getTransactionTime().getTime() < au.getTransactionTime().getTime()) {
                userMap.replace(au.getId(), au);
            }
        }
        userList.addAll(userMap.values());
        Integer num = userList.size();
        int totalPage = (int)Math.ceil(num * 1.0 / CURRENT_COUNT);
        page.setTotalCount(num);
        page.setTotalPage(totalPage);
        page.setCurrentCount(listNum);
        page.setCurrentPage(currentPage);
        page.setListForObject(userList.subList(start, Math.min(userList.size(), start + listNum)));
        return page;
    }
}
